﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.Revit;
using YJKArchMethodLibrary.Utils;

namespace WallCreateAndEdit.WallModule
{
	public class WallJoinOperator
	{
		public bool SetSingleUnJoinWall(ExternalCommandData commandData)
		{
			Document document = commandData.Application.ActiveUIDocument.Document;
			UIDocument activeUIDocument = commandData.Application.ActiveUIDocument;
			this.m_CommandData = commandData;
			Reference reference = null;
			Selection selection = commandData.Application.ActiveUIDocument.Selection;
			try
			{
				string text = "选择被打断墙体的一端";
				reference = selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, new WallFilter(), text);
			}
			catch (Exception)
			{
				return false;
			}
			XYZ globalPoint = reference.GlobalPoint;
			Element element = document.GetElement(reference);
			Wall wall = element as Wall;
			if (wall == null)
			{
				MessageBox.Show("请选择墙体", "盈建科提示");
				return true;
			}
			List<Wall> list = new List<Wall>();
			if (!this.IniWall(document, wall, out list))
			{
				return true;
			}
			double maxValue = double.MaxValue;
			Wall wall2 = null;
			bool nearWallFromWall = this.GetNearWallFromWall(document, list[0], globalPoint, out wall2, out maxValue);
			double maxValue2 = double.MaxValue;
			int num = 2;
			List<Wall> vertWallsWith2EndPoint = this.GetVertWallsWith2EndPoint(list[0], globalPoint, out num, out maxValue2);
			if (num != 0 && num != 1 && !nearWallFromWall)
			{
				YJKMessageBox.Show("该墙无可断开处！");
				return true;
			}
			if (Geometry.LessThan(maxValue, maxValue2))
			{
				if (!this.IsVertWall2Wall(list[0], wall2))
				{
					YJKMessageBox.Show("该功能仅支持相互垂直的墙断开！");
					return true;
				}
				this.CancleWallsConnect(document, list[0], wall2);
			}
			else
			{
				int num2 = vertWallsWith2EndPoint.Count;
				this.ModifyVertWalls(activeUIDocument, vertWallsWith2EndPoint, list[0], num);
				for (int i = 1; i < list.Count; i++)
				{
					vertWallsWith2EndPoint = this.GetVertWallsWith2EndPoint(list[i], globalPoint, out num, out maxValue2);
					if (num == 0 || num == 1)
					{
						this.ModifyVertWalls(activeUIDocument, vertWallsWith2EndPoint, list[i], num);
						num2 += vertWallsWith2EndPoint.Count;
					}
				}
				if (num2 == 0)
				{
					YJKMessageBox.Show("该功能仅支持相互垂直的墙断开！");
				}
			}
			return true;
		}

		private bool IniWall(Document doc, Wall wall, out List<Wall> lstSqlWall)
		{
			lstSqlWall = new List<Wall>();
			if (wall.IsStackedWall)
			{
				IList<ElementId> stackedWallMemberIds = wall.GetStackedWallMemberIds();
				if (stackedWallMemberIds.Count == 0)
				{
					return false;
				}
				IEnumerator<ElementId> enumerator = stackedWallMemberIds.GetEnumerator();
				{
					while (enumerator.MoveNext())
					{
						ElementId elementId = enumerator.Current;
						Element elementById = doc.GetElementById(elementId);
						if (elementById != null)
						{
							Wall wall2 = elementById as Wall;
							if (wall2 != null)
							{
								lstSqlWall.Add(wall2);
							}
						}
					}
					goto IL_6E;
				}
			}
			lstSqlWall.Add(wall);
			IL_6E:
			return lstSqlWall.Count != 0;
		}

		private bool IsCommonWalls(Document doc, List<Wall> lstWall)
		{
			for (int i = 0; i < lstWall.Count; i++)
			{
				for (int j = i; j < lstWall.Count; j++)
				{
					if (!this.IsCommonWalls(doc, lstWall[i], lstWall[j]))
					{
						return false;
					}
				}
			}
			return true;
		}

		private bool IsCommonWalls(Document doc, Wall wall_1, Wall wall_2)
		{
			if (wall_1.IsStackedWallMember)
			{
				wall_1 = (doc.GetElementById(wall_1.StackedWallOwnerId) as Wall);
			}
			if (wall_2.IsStackedWallMember)
			{
				wall_2 = (doc.GetElementById(wall_2.StackedWallOwnerId) as Wall);
			}
			return wall_1.Id == wall_2.Id;
		}

		private void ModifyVertWalls(UIDocument uiDoc, List<Wall> lstPointWalls, Wall wall, int iEndPoint)
		{
			if (lstPointWalls.Count == 0)
			{
				return;
			}
			XYZ xyz = null;
			Line line = null;
			if (!this.GetWallVec(wall, ref xyz, ref line))
			{
				return;
			}
			XYZ xyz2 = null;
			if (this.IsCommonWalls(uiDoc.Document, lstPointWalls))
			{
				for (int i = 0; i < lstPointWalls.Count; i++)
				{
					Wall wall2 = lstPointWalls[i];
					int iEndPoint2 = 0;
					if (this.IsNeedModifyWall(wall2, wall, out iEndPoint2))
					{
						this.CancleEndPointWallsConnect(uiDoc, wall2, iEndPoint2);
						if (this.Get2WallProjectPoint(uiDoc, wall2, wall, false, out xyz2))
						{
							this.ModifyWallLocalCurve(uiDoc.Document, ref wall2, xyz2);
						}
					}
				}
			}
			double val = double.MaxValue;
			XYZ endPoint = line.GetEndPoint(0);
			if (iEndPoint == 0)
			{
				endPoint = line.GetEndPoint(1);
			}
			if (iEndPoint == 0 || iEndPoint == 1)
			{
				this.CancleEndPointWallsConnect(uiDoc, wall, iEndPoint);
			}
			xyz2 = null;
			foreach (Wall refWall in lstPointWalls)
			{
				XYZ xyz3 = null;
				if (this.Get2WallProjectPoint(uiDoc, wall, refWall, true, out xyz3) && Geometry.LessThan(endPoint.DistanceTo(xyz3), val))
				{
					xyz2 = xyz3;
					val = endPoint.DistanceTo(xyz3);
				}
			}
			if (xyz2 != null)
			{
				this.ModifyWallLocalCurve(uiDoc.Document, ref wall, xyz2);
			}
		}

		private List<Wall> GetWallsFromWall(Document doc, Wall wall)
		{
			List<Wall> list = new List<Wall>();
			if (wall.IsStackedWall)
			{
				IList<ElementId> stackedWallMemberIds = wall.GetStackedWallMemberIds();
				IEnumerator<ElementId> enumerator = stackedWallMemberIds.GetEnumerator();
				{
					while (enumerator.MoveNext())
					{
						ElementId elementId = enumerator.Current;
						Element elementById = doc.GetElementById(elementId);
						if (elementById != null)
						{
							Wall wall2 = elementById as Wall;
							if (wall2 != null)
							{
								list.Add(wall2);
							}
						}
					}
					return list;
				}
			}
			if (wall.IsStackedWallMember)
			{
				Wall wall3 = doc.GetElementById(wall.StackedWallOwnerId) as Wall;
				if (wall3 == null)
				{
					return list;
				}
				IList<ElementId> stackedWallMemberIds2 = wall3.GetStackedWallMemberIds();
				IEnumerator<ElementId> enumerator2 = stackedWallMemberIds2.GetEnumerator();
				{
					while (enumerator2.MoveNext())
					{
						ElementId elementId2 = enumerator2.Current;
						Element elementById2 = doc.GetElementById(elementId2);
						if (elementById2 != null)
						{
							Wall wall4 = elementById2 as Wall;
							if (wall4 != null)
							{
								list.Add(wall4);
							}
						}
					}
					return list;
				}
			}
			list.Add(wall);
			return list;
		}

		private void CancleWallsConnect(Document doc, Wall wall, Wall wallTmp)
		{
			List<Wall> wallsFromWall = this.GetWallsFromWall(doc, wall);
			List<Wall> wallsFromWall2 = this.GetWallsFromWall(doc, wallTmp);
			Transaction transaction = new Transaction(doc, "CancelWallConnect");
			try
			{
				transaction.Start();
				if (wall.IsStackedWall && wallTmp.IsStackedWall && JoinGeometryUtils.AreElementsJoined(doc, wall, wallTmp))
				{
					JoinGeometryUtils.UnjoinGeometry(doc, wallTmp, wall);
				}
				for (int i = 0; i < wallsFromWall.Count; i++)
				{
					for (int j = 0; j < wallsFromWall2.Count; j++)
					{
						if (JoinGeometryUtils.AreElementsJoined(doc, wallsFromWall[i], wallsFromWall2[j]))
						{
							JoinGeometryUtils.UnjoinGeometry(doc, wallsFromWall[i], wallsFromWall2[j]);
						}
					}
				}
				transaction.Commit();
			}
			catch
			{
				transaction.RollBack();
			}
		}

		private bool IsNeedModifyWall(Wall modifyWall, Wall wallRef, out int iInx)
		{
			iInx = 0;
			LocationCurve locationCurve = modifyWall.Location as LocationCurve;
			if (locationCurve == null)
			{
				return false;
			}
			ElementArray elementArray = locationCurve.get_ElementsAtJoin(0);
			foreach (object obj in elementArray)
			{
				Wall wall = obj as Wall;
				if (wallRef.Id == wall.Id)
				{
					return true;
				}
			}
			iInx = 1;
			ElementArray elementArray2 = locationCurve.get_ElementsAtJoin(1);
			foreach (object obj2 in elementArray2)
			{
				Wall wall2 = obj2 as Wall;
				if (wallRef.Id == wall2.Id)
				{
					return true;
				}
			}
			return false;
		}

		private void CancleEndPointWallsConnect(UIDocument uiDoc, Wall wall, int iEndPoint)
		{
			Transaction transaction = new Transaction(uiDoc.Document, "CancelEndPointWallConnect");
			try
			{
				transaction.Start();
				WallUtils.DisallowWallJoinAtEnd(wall, iEndPoint);
				this.UpdateModel(uiDoc, true);
				transaction.Commit();
			}
			catch
			{
				transaction.RollBack();
			}
		}

		private bool ModifyWallLocalCurve(Document doc, ref Wall wall, XYZ locationPoint)
		{
			if (wall == null)
			{
				return false;
			}
			LocationCurve locationCurve = wall.Location as LocationCurve;
			if (locationCurve == null)
			{
				return false;
			}
			Line line = locationCurve.Curve as Line;
			if (line == null)
			{
				return false;
			}
			Transaction transaction = new Transaction(doc, "ModelWall");
			try
			{
				if (Geometry.LessThan(line.GetEndPoint(0).DistanceTo(locationPoint), line.GetEndPoint(1).DistanceTo(locationPoint)))
				{
					line = Line.CreateBound(locationPoint, line.GetEndPoint(1));
				}
				else
				{
					line = Line.CreateBound(line.GetEndPoint(0), locationPoint);
				}
				transaction.Start();
				locationCurve.Curve = line;
				transaction.Commit();
			}
			catch
			{
				transaction.RollBack();
				return false;
			}
			return true;
		}

		private FaceArray GetWallFaces(UIDocument uiDoc, Wall refWall)
		{
			FaceArray faceArray = new FaceArray();
			if (refWall.IsStackedWallMember)
			{
				Wall wall = uiDoc.Document.GetElementById(refWall.StackedWallOwnerId) as Wall;
				if (wall == null)
				{
					return faceArray;
				}
				IList<ElementId> stackedWallMemberIds = wall.GetStackedWallMemberIds();
				IEnumerator<ElementId> enumerator = stackedWallMemberIds.GetEnumerator();
				{
					while (enumerator.MoveNext())
					{
						ElementId elementId = enumerator.Current;
						Wall wall2 = uiDoc.Document.GetElementById(elementId) as Wall;
						if (wall2 != null)
						{
							Solid elementSolid = this.GetElementSolid(wall2);
							if (!(elementSolid == null))
							{
								foreach (object obj in elementSolid.Faces)
								{
									Face face = (Face)obj;
									faceArray.Append(face);
								}
							}
						}
					}
					return faceArray;
				}
			}
			Solid elementSolid2 = this.GetElementSolid(refWall);
			if (elementSolid2 == null)
			{
				return faceArray;
			}
			foreach (object obj2 in elementSolid2.Faces)
			{
				Face face2 = (Face)obj2;
				faceArray.Append(face2);
			}
			return faceArray;
		}

		private bool Get2WallProjectPoint(UIDocument uiDoc, Wall modifyWall, Wall refWall, bool bShort, out XYZ newPoint)
		{
			newPoint = null;
			XYZ xyz = null;
			Line line = null;
			if (!this.GetWallVec(modifyWall, ref xyz, ref line))
			{
				return false;
			}
			XYZ endPoint = line.GetEndPoint(0);
			XYZ endPoint2 = line.GetEndPoint(1);
			XYZ xyz2 = null;
			Line line2 = null;
			if (!this.GetWallVec(refWall, ref xyz2, ref line2))
			{
				return false;
			}
			XYZ endPoint3 = line2.GetEndPoint(0);
			XYZ endPoint4 = line2.GetEndPoint(1);
			XYZ xyz3 = null;
			XYZ xyz4;
			if (Geometry.LessThan(line2.Distance(endPoint), line2.Distance(endPoint2)))
			{
				xyz4 = endPoint;
				xyz3 = endPoint2;
			}
			else
			{
				xyz4 = endPoint2;
				xyz3 = endPoint;
			}
			if (Geometry.LessThan(line.Distance(endPoint3), line.Distance(endPoint4)))
			{
				xyz2 = (endPoint3 - endPoint4).Normalize();
			}
			else
			{
				xyz2 = (endPoint4 - endPoint3).Normalize();
			}
			xyz4 -= 0.98425196850393692 * xyz2;
			FaceArray wallFaces = this.GetWallFaces(uiDoc, refWall);
			double val = double.MaxValue;
			double val2 = double.MinValue;
			foreach (object obj in wallFaces)
			{
				Face face = (Face)obj;
				PlanarFace planarFace = face as PlanarFace;
				if (!(planarFace == null))
				{
					XYZ xyz5 = planarFace.FaceNormal();
					double length = (xyz + xyz5).GetLength();
					if (xyz.IsAlmostEqualTo(xyz5) || Geometry.IsEqual(length, 0.0))
					{
						IntersectionResult intersectionResult = face.Project(xyz4);
						if (intersectionResult != null)
						{
							XYZ xyzpoint = intersectionResult.XYZPoint;
							if (bShort)
							{
								if (Geometry.LessThan(xyz3.DistanceTo(xyzpoint), val))
								{
									newPoint = xyzpoint;
									val = xyz3.DistanceTo(xyzpoint);
								}
							}
							else if (Geometry.LessThan(val2, xyz3.DistanceTo(xyzpoint)))
							{
								newPoint = xyzpoint;
								val2 = xyz3.DistanceTo(xyzpoint);
							}
						}
					}
				}
			}
			if (newPoint == null)
			{
				return false;
			}
			newPoint += 0.98425196850393692 * xyz2;
			double val3 = xyz3.DistanceTo(newPoint);
			if (bShort)
			{
				return !Geometry.LessThan(line.Length, val3);
			}
			return Geometry.LessThan(line.Length, val3);
		}

		public Solid GetElementSolid(Element curElement)
		{
			Solid result;
			try
			{
				Options options = this.m_CommandData.Application.Application.Create.NewGeometryOptions();
                options.DetailLevel = (ViewDetailLevel)3;
				options.IncludeNonVisibleObjects = true;
				GeometryElement geometryElement;
				if (curElement.GetType() == typeof(FamilyInstance))
				{
					FamilyInstance familyInstance = curElement as FamilyInstance;
					geometryElement = familyInstance.GetOriginalGeometry(options);
					geometryElement = geometryElement.GetTransformed(familyInstance.GetTransform());
				}
				else
				{
					geometryElement = curElement.get_Geometry(options);
				}
				if (null == geometryElement)
				{
					result = null;
				}
				else
				{
					foreach (GeometryObject geometryObject in geometryElement)
					{
						if (!(geometryObject.GetType() != typeof(Solid)))
						{
							Solid solid = geometryObject as Solid;
							if (solid != null && Geometry.GreaterThan(solid.Volume, 0.0))
							{
								return solid;
							}
						}
					}
					result = null;
				}
			}
			catch (Exception)
			{
				result = null;
			}
			return result;
		}

		private List<Wall> GetVertWallsWith2EndPoint(Wall targetWall, XYZ ptPoint, out int iEndPoint, out double dMinLength)
		{
			List<Wall> list = new List<Wall>();
			dMinLength = double.MaxValue;
			list = this.GetVertWallsWith2EndPoint(targetWall, ptPoint, out iEndPoint);
			XYZ xyz = null;
			Line line = null;
			foreach (Wall wall in list)
			{
				if (this.GetWallVec(wall, ref xyz, ref line) && Geometry.LessThan(line.Distance(ptPoint), dMinLength))
				{
					dMinLength = line.Distance(ptPoint);
				}
			}
			return list;
		}

		private List<Wall> GetVertWallsWith2EndPoint(Wall targetWall, XYZ ptPoint, out int iEndPoint)
		{
			List<Wall> result = new List<Wall>();
			iEndPoint = 2;
			if (targetWall == null)
			{
				return result;
			}
			LocationCurve locationCurve = targetWall.Location as LocationCurve;
			if (locationCurve == null)
			{
				return result;
			}
			Line line = locationCurve.Curve as Line;
			if (line == null)
			{
				return result;
			}
			XYZ hyendPoint = line.GetEndPoint(0);
			XYZ hyendPoint2 = line.GetEndPoint(1);
			(hyendPoint - hyendPoint2).Normalize();
			if (Geometry.LessThan((ptPoint - hyendPoint).GetLength(), (ptPoint - hyendPoint2).GetLength()))
			{
				List<Wall> locationPointWalls = this.GetLocationPointWalls(locationCurve, 0);
				if (locationPointWalls.Count > 0)
				{
					iEndPoint = 0;
					return this.GetVertWallsWithLocalCurve(locationPointWalls, targetWall);
				}
				locationPointWalls = this.GetLocationPointWalls(locationCurve, 1);
				if (locationPointWalls.Count > 0)
				{
					iEndPoint = 1;
					return this.GetVertWallsWithLocalCurve(locationPointWalls, targetWall);
				}
			}
			else
			{
				List<Wall> locationPointWalls2 = this.GetLocationPointWalls(locationCurve, 1);
				if (locationPointWalls2.Count > 0)
				{
					iEndPoint = 1;
					return this.GetVertWallsWithLocalCurve(locationPointWalls2, targetWall);
				}
				locationPointWalls2 = this.GetLocationPointWalls(locationCurve, 0);
				if (locationPointWalls2.Count > 0)
				{
					iEndPoint = 0;
					return this.GetVertWallsWithLocalCurve(locationPointWalls2, targetWall);
				}
			}
			return result;
		}

		private List<Wall> GetVertWallsWithLocalCurve(List<Wall> lstWallTmp, Wall wall)
		{
			List<Wall> list = new List<Wall>();
			foreach (Wall wall2 in lstWallTmp)
			{
				if (this.IsVertWall2Wall(wall2, wall))
				{
					list.Add(wall2);
				}
			}
			return list;
		}

		private bool IsVertWall2Wall(Wall wall_1, Wall wall_2)
		{
			LocationCurve locationCurve = wall_1.Location as LocationCurve;
			LocationCurve locationCurve2 = wall_2.Location as LocationCurve;
			if (locationCurve == null || locationCurve2 == null)
			{
				return false;
			}
			Line line = locationCurve.Curve as Line;
			Line line2 = locationCurve2.Curve as Line;
			if (line == null || line2 == null)
			{
				return false;
			}
			XYZ xyz = line.GetEndPoint(0) - line.GetEndPoint(1);
			XYZ xyz2 = line2.GetEndPoint(0) - line2.GetEndPoint(1);
			return Geometry.IsEqual(xyz.DotProduct(xyz2), 0.0);
		}

		private List<Wall> GetLocationPointWalls(LocationCurve locationCv, int inx)
		{
			List<Wall> list = new List<Wall>();
			if (inx != 1 && inx != 0)
			{
				return list;
			}
			ElementArray elementArray = locationCv.get_ElementsAtJoin(inx);
			foreach (object obj in elementArray)
			{
				Wall wall = obj as Wall;
				if (wall != null)
				{
					string a = wall.get_Parameter(BuiltInParameter.ELEM_FAMILY_PARAM).AsValueString();
					if (!(a == "幕墙"))
					{
						list.Add(wall);
					}
				}
			}
			return list;
		}

		private bool GetNearWallFromWall(Document doc, Wall wall, XYZ ptPoint, out Wall nearWall, out double dMaxLength)
		{
			dMaxLength = double.MaxValue;
			nearWall = null;
			XYZ xyz = null;
			Line line = null;
			if (!this.GetWallVec(wall, ref xyz, ref line))
			{
				return false;
			}
			ICollection<ElementId> joinedElements = JoinGeometryUtils.GetJoinedElements(doc, wall);
			foreach (ElementId elementId in joinedElements)
			{
				Element element = doc.GetElement(elementId);
				if (element != null)
				{
					Wall wall2 = element as Wall;
					if (wall2 != null)
					{
						string a = wall2.get_Parameter(BuiltInParameter.ELEM_FAMILY_PARAM).AsValueString();
						if (!(a == "幕墙") && !wall2.IsStackedWall)
						{
							XYZ xyz2 = null;
							Line line2 = null;
							if (this.GetWallVec(wall2, ref xyz2, ref line2))
							{
								XYZ xyz3 = null;
								IntersectionResultArray intersectionResultArray = new IntersectionResultArray();
								SetComparisonResult setComparisonResult = line.Intersect(line2, out intersectionResultArray);
                                if ((SetComparisonResult)4 != setComparisonResult && intersectionResultArray != null && !intersectionResultArray.IsEmpty && intersectionResultArray.Size == 1)
								{
                                    xyz3 = intersectionResultArray.get_Item(0).XYZPoint;
								}
								if (xyz3 != null && Geometry.LessThan(xyz3.DistanceTo(ptPoint), dMaxLength))
								{
									dMaxLength = xyz3.DistanceTo(ptPoint);
									nearWall = wall2;
								}
							}
						}
					}
				}
			}
			return nearWall != null;
		}

		private bool GetWallVec(Wall wall, ref XYZ vec, ref Line line)
		{
			if (wall == null)
			{
				return false;
			}
			LocationCurve locationCurve = wall.Location as LocationCurve;
			if (locationCurve == null)
			{
				return false;
			}
			line = (locationCurve.Curve as Line);
			if (line == null)
			{
				return false;
			}
			if (line.IsBound)
			{
				vec = (line.GetEndPoint(0) - line.GetEndPoint(1)).Normalize();
			}
			else
			{
				vec = line.Direction.Normalize();
			}
			return true;
		}

		public bool SetSingle(ExternalCommandData m_Revit, JoinType joinType)
		{
			Document document = m_Revit.Application.ActiveUIDocument.Document;
			Reference reference = null;
			Selection selection = m_Revit.Application.ActiveUIDocument.Selection;
			try
			{
				string text = (joinType == JoinType.UnJoin) ? "选择被打断墙体的一端" : "选择需要与相交墙体自动连接的墙体一端";
				reference = selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, new WallFilter(), text);
			}
			catch (Exception)
			{
				return false;
			}
			XYZ globalPoint = reference.GlobalPoint;
			Element element = document.GetElement(reference);
			Wall wall = element as Wall;
			if (wall == null)
			{
				MessageBox.Show("请选择墙体", "盈建科提示");
				return true;
			}
			LocationCurve locationCurve = wall.Location as LocationCurve;
			Curve curve = locationCurve.Curve;
			XYZ hyendPoint = curve.GetEndPoint(0);
			XYZ hyendPoint2 = curve.GetEndPoint(1);
			double length = (globalPoint - hyendPoint).GetLength();
			double length2 = (globalPoint - hyendPoint2).GetLength();
			if (Geometry.LessThan(length, length2))
			{
				if (joinType == JoinType.UnJoin)
				{
					WallUtils.DisallowWallJoinAtEnd(wall, 0);
				}
				else
				{
					WallUtils.AllowWallJoinAtEnd(wall, 0);
				}
			}
			else if (joinType == JoinType.UnJoin)
			{
				WallUtils.DisallowWallJoinAtEnd(wall, 1);
			}
			else
			{
				WallUtils.AllowWallJoinAtEnd(wall, 1);
			}
			this.UpdateModel(m_Revit.Application.ActiveUIDocument, true);
			return true;
		}

		public bool SetOne(ExternalCommandData m_Revit, JoinType joinType)
		{
			Document document = m_Revit.Application.ActiveUIDocument.Document;
			Reference reference = null;
			Selection selection = m_Revit.Application.ActiveUIDocument.Selection;
			try
			{
				string text = (joinType == JoinType.UnJoin) ? "选择被打断墙体" : "选择需要与相交墙体自动连接的墙体";
				reference = selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, new WallFilter(), text);
			}
			catch (Exception)
			{
				return false;
			}
			Element element = document.GetElement(reference);
			Wall wall = element as Wall;
			if (wall == null)
			{
				MessageBox.Show("请选择墙体", "盈建科提示");
				return true;
			}
			if (joinType == JoinType.UnJoin)
			{
				WallUtils.DisallowWallJoinAtEnd(wall, 0);
				WallUtils.DisallowWallJoinAtEnd(wall, 1);
			}
			else
			{
				WallUtils.AllowWallJoinAtEnd(wall, 0);
				WallUtils.AllowWallJoinAtEnd(wall, 1);
			}
			this.UpdateModel(m_Revit.Application.ActiveUIDocument, true);
			return true;
		}

		public bool SetMulti(ExternalCommandData m_Revit, JoinType joinType)
		{
			Document document = m_Revit.Application.ActiveUIDocument.Document;
			IList<Element> list = null;
			Selection selection = m_Revit.Application.ActiveUIDocument.Selection;
			try
			{
				string text = (joinType == JoinType.UnJoin) ? "框选被打断墙体" : "框选需要与相交墙体自动连接的墙体";
				list = selection.PickElementsByRectangle(new WallFilter(), text);
			}
			catch (Exception)
			{
				return false;
			}
			foreach (Element element in list)
			{
				Wall wall = element as Wall;
				if (wall == null)
				{
					MessageBox.Show("请选择墙体", "盈建科提示");
				}
				else if (joinType == JoinType.UnJoin)
				{
					WallUtils.DisallowWallJoinAtEnd(wall, 0);
					WallUtils.DisallowWallJoinAtEnd(wall, 1);
				}
				else
				{
					WallUtils.AllowWallJoinAtEnd(wall, 0);
					WallUtils.AllowWallJoinAtEnd(wall, 1);
				}
			}
			this.UpdateModel(m_Revit.Application.ActiveUIDocument, true);
			return true;
		}

		private void UpdateModel(UIDocument uiDoc, bool autoJoin)
		{
			uiDoc.Document.Regenerate();
			if (autoJoin)
			{
				uiDoc.Document.AutoJoinElements();
			}
			uiDoc.RefreshActiveView();
		}

		private ExternalCommandData m_CommandData;
	}
}
